package online

import (
	"fmt"
	"server/common"

	"github.com/mitchellh/mapstructure"
	"github.com/sirupsen/logrus"
)

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *OnlineService) handleConnClosedNotify(msg common.Message, from common.ServiceInfo,
	connId string) error {
	common.Logger(common.SERVICE_TYPE_ONLINE, msg.Rid).WithFields(logrus.Fields{
		"msg":  common.ToJson(msg),
		"from": from,
	}).Info("call handleConnClosedNotify")

	// 1. 将 msg.Data 断言为 map[string]interface{}
	dataMap, ok := msg.Data.(map[string]interface{})
	if !ok {
		err := fmt.Errorf("invalid data format for connection closed notify: not a map")
		common.Logger(common.SERVICE_TYPE_ONLINE, msg.Rid).Error(err)
		return err
	}

	// 2. 使用 mapstructure 解码到结构体
	var notifyData common.ConnClosedNotifyData
	if err := mapstructure.Decode(dataMap, &notifyData); err != nil {
		err = fmt.Errorf("failed to decode conn closed notify data: %w", err)
		common.Logger(common.SERVICE_TYPE_ONLINE, msg.Rid).Error(err)
		return err
	}

	// 3. 从结构体中获取 ConnId 并进行验证
	if notifyData.ConnId == "" {
		err := fmt.Errorf("connId is empty in connection closed notify")
		common.Logger(common.SERVICE_TYPE_ONLINE, msg.Rid).Error(err)
		return err
	}

	// 4. 使用获取到的 connId 移除客户端
	user := s.userMgr.GetUserByConnId(notifyData.ConnId)
	if user == nil {
		common.Logger(common.SERVICE_TYPE_ONLINE, msg.Rid).Error("user not found for connId")
		return nil
	}
	s.userMgr.RemoveUserByConnId(notifyData.ConnId)

	LOG(msg.Rid).WithFields(logrus.Fields{
		"user_id": user.UserId,
		"conn_id": notifyData.ConnId,
	}).Info("User disconnected, removing from user manager")

	// 5. 发送登出通知给其他用户
	for _, client := range s.userMgr.GetUserListWithoutSelf(user.UserId) {
		notifyMsg := common.Message{
			Cmd: common.LOGOUT_NOTIFY,
			Rid: msg.Rid,
			Data: common.LogoutNotifyData{
				UserId: user.UserId,
			},
		}
		s.dispatcher.Dispatch(notifyMsg, s.serviceInfo, client.ServiceInfo, client.ConnId)
	}

	// 6. 发送用户下线通知
	offlineMsg := common.Message{
		Cmd: common.USER_OFFLINE_NOTIFY,
		Rid: msg.Rid,
		Data: common.UserOfflineNotifyData{
			UserId: user.UserId,
		},
	}
	s.dispatcher.Dispatch(offlineMsg, s.serviceInfo, common.ServiceInfo{
		ServiceType: common.SERVICE_TYPE_ROOM}, "")

	return nil
}
